package com.AndroidKids;

// imports
import java.util.Random;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RadioGroup;

// main class
public class AndroidKids extends Activity {

	// globals start
	public int numberOfLevels = 3;				// only for mode 1; number of levels before winning the game
	public int difficulty = 1;					// 1:easy; 2:intermediate; 3:hard -- only for mode 1
	public int mode = 1;						// 1 (equations) or 2 (24-puzzle)
	public int gridSize1 = 5;					// mode 1 only
	public int gridSize2 = 5;					// mode 2 only
	public int gridSize = 5;					// gridSize1 or gridSize2 get loaded into this variable
	public int settings_difficulty = difficulty;// allow settings to be cancelled
	public int settings_gridSize = gridSize;	// allow settings to be cancelled
	public int sound_success = 1;				// assign this sound an ID
	public int sound_move_tile = 2;				// assign this sound an ID
	public int sound_bad_selection = 3;			// assign this sound an ID
	public int sound_equation_found = 4;		// assign this sound an ID
	public int sound_background_music = 5;		// assign this sound an ID
	public int equationsFound = 0;				// only for mode 1; track the number of equations found (to compare to the number needed to advance a level)
	public int blank;							// track the blank
	public int level = 1;						// only for mode 1; tracks the current level of the game
	public int minimumAnswersOnANewBoard = ((level*5)+9);					// the board gets re-created if it starts with fewer than this many valid equations
	public int max_possible_equations = 108;								// the number of possible valid equations, given our constraints
	public String[] tileText = new String[gridSize*gridSize]; 				// track the text/image assigned to each tile
	public String[] completedEquations = new String[max_possible_equations];// track the equations that have been found
	public int[] tileDrawableId = new int[gridSize*gridSize];				// array of resource IDs associated with each tile
	public int[] levelRequirements = new int[numberOfLevels];				// only for mode 1; the number of equations needed to pass each level
	public boolean gameInProgress = false;									// if a game is in progress and you leave to the menu, show the "resume game" button
	public boolean goalTypeAlternative = false;									// track which goal state is possible, based on the starting configuration
	// globals end

	// create a sound manager to handle sounds
	private SoundManager mSoundManager;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// begin by showing the logo
		setContentView(R.layout.logo);

		// create the sound manager, and add the sounds to it
		mSoundManager = new SoundManager();
		mSoundManager.initSounds(getBaseContext());
		mSoundManager.addSound(sound_success, R.raw.success);
		mSoundManager.addSound(sound_move_tile, R.raw.move_tile);
		mSoundManager.addSound(sound_bad_selection, R.raw.bad_selection);
		mSoundManager.addSound(sound_equation_found, R.raw.equation_found);
		mSoundManager.addSound(sound_background_music, R.raw.ambience);

		// delay 2.5 seconds before going to the menu screen (showing logo in the meantime)
		Handler handler = new Handler(); 
		handler.postDelayed(new Runnable(){public void run(){ menu(); }}, 2500);
		//menu();
	}

	// load game variables and environment
	public void game(){

		// move to the game screen
		setContentView(R.layout.game);

		// set the level requirements for mode 1, based on the difficulty
		if(mode == 1){
			for(int i=0; i<numberOfLevels; i++){
				if(difficulty == 1){levelRequirements[i] = (3+(2*i));}
				else if(difficulty == 2){levelRequirements[i] = (5+(4*i));}
				else if(difficulty == 3){levelRequirements[i] = (7+(6*i));}
				if(levelRequirements[i] > max_possible_equations){
					minimumAnswersOnANewBoard = max_possible_equations;
					levelRequirements[i] = max_possible_equations;
				}
			}
		}

		// remove unnecessary elements from the game view
		remove_unnecessary_elements();

		// load a new random board
		newGame_load();
	}
	
	// remove unnecessary elements from the game view
	public void remove_unnecessary_elements(){
		if(mode == 1){

			// hide the goal-preview
			Button gt = (Button) findViewById(R.id.goalTitle);
			gt.setVisibility(4); // invisible
			ImageButton currentTile = (ImageButton) findViewById(R.id.tile1g);
			for(int i=0; i<25; i++){ // keep this 25! if supporting up to 5*5 grid in mode 2...

				// hide the goal-preview tile
				currentTile.setVisibility(4); // 0 is visible; 4 is invisible

				// get next tile
				if(i != 24){
					currentTile = (ImageButton) findViewById(currentTile.getNextFocusForwardId());
				}
			}
		}
		else if(mode == 2){

			// hide unnecessary tiles, based on the grid size
			int j = 1;
			ImageButton currentTile = (ImageButton) findViewById(R.id.tile1);
			for(int i=0; i<25; i++){ // keep this 25! if supporting up to 5*5 grid...
				if(j > (gridSize*gridSize)){ // all tiles placed
					currentTile.setVisibility(4); // 0 is visible; 4 is invisible
				}
				else if(((i%5)+1) > gridSize){ // column out of bounds
					currentTile.setVisibility(4); // 0 is visible; 4 is invisible
				}
				else{
					// contentDescription = j
					currentTile.setContentDescription(Integer.toString(j));
					j++;
				}
	
				// get next tile
				if(i != 24){
					currentTile = (ImageButton) findViewById(currentTile.getNextFocusForwardId());
				}
			}
			
			// hide unnecessary elements
			EditText lt = (EditText) findViewById(R.id.levelTitle);
			lt.setVisibility(4); // 0 is visible; 4 is invisible
	
			ProgressBar pb = (ProgressBar) findViewById(R.id.progressBar);
			pb.setVisibility(4); // 0 is visible; 4 is invisible
	
			EditText edt = (EditText) findViewById(R.id.equationsDoneTitle);
			edt.setVisibility(4); // 0 is visible; 4 is invisible
	
			EditText ed = (EditText) findViewById(R.id.equationsDone);
			ed.setVisibility(4); // 0 is visible; 4 is invisible
		}
	}

	// start a game in mode 1
	public void game1(View view){

		// update mode 1 - specific variables
		mode = 1;
		gridSize = gridSize1;
		level = 1;
		equationsFound = 0;

		// load game variables and environment
		game();
	}

	// start a game in mode 2
	public void game2(View view){

		// update mode 2 - specific variables
		mode = 2;
		gridSize = gridSize2;

		// load game variables and environment
		game();
	}

	// resume a game in progress
	public void resumeGame(View view){

		// move to the game screen
		setContentView(R.layout.game);

		// restore tiles
		for(int i=0; i<(gridSize*gridSize); i++){
			setTileDrawableId(i, tileText[i]);
		}
		setTiles();

		// restore mode 1 - specific state
		if(mode == 1){
			EditText lt = (EditText) findViewById(R.id.levelTitle);
			lt.setText("Level "+level+" of "+numberOfLevels);

			ProgressBar pb = (ProgressBar) findViewById(R.id.progressBar);
			pb.setProgress((equationsFound*100)/levelRequirements[level-1]);

			EditText edt = (EditText) findViewById(R.id.equationsDoneTitle);
			edt.setText("Equations Found:\r\n "+equationsFound+" of "+levelRequirements[level-1]+" ("+Integer.toString(getPossibleAnswers())+" possible)");

			for(int i=0; i<equationsFound; i++){
				EditText ed = (EditText) findViewById(R.id.equationsDone);
				ed.setText(ed.getText()+"Equation Found: "+completedEquations[i]+"\r\n");
			}
		}

		// restore mode 2 - specific state
		else if(mode == 2){
			remove_unnecessary_elements();
		}
	}

	// load the menu screen (not from a button)
	public void menu(){

		// move to the menu screen
		setContentView(R.layout.menu);
		
		mSoundManager.playSound(sound_background_music);
	}

	// load the menu screen (from a button)
	public void menu(View view){

		// move to the menu screen
		setContentView(R.layout.menu);

		mSoundManager.playSound(sound_background_music);
		
		// set the "resume game" button if needed
		if(gameInProgress){
			Button resume = (Button) findViewById(R.id.resumeGame);
			resume.setVisibility(0); // 0 is visible; 4 is invisible
			Button resumeBG = (Button) findViewById(R.id.resumeGameBG);
			resumeBG.setVisibility(0); // 0 is visible; 4 is invisible
		}
		else{
			Button resume = (Button) findViewById(R.id.resumeGame);
			resume.setVisibility(4); // 0 is visible; 4 is invisible
			Button resumeBG = (Button) findViewById(R.id.resumeGameBG);
			resumeBG.setVisibility(4); // 0 is visible; 4 is invisible
		}
	}

	// load the settings screen
	public void settings(View view){

		// move to the settings screen
		setContentView(R.layout.settings);

		// select the appropriate difficulty
		RadioGroup rgd = (RadioGroup) findViewById(R.id.difficulty);
		rgd.clearCheck();
		if(difficulty == 1){
			rgd.check(R.id.difficulty_easy);
		}
		else if(difficulty == 2){
			rgd.check(R.id.difficulty_intermediate);
		}
		else if(difficulty == 3){
			rgd.check(R.id.difficulty_advanced);
		}

		// select the appropriate grid size
		RadioGroup rggs = (RadioGroup) findViewById(R.id.grid_size);
		rggs.clearCheck();
		if(gridSize2 == 2){
			rggs.check(R.id.grid_size_2);
		}
		else if(gridSize2 == 3){
			rggs.check(R.id.grid_size_3);
		}
		else if(gridSize2 == 4){
			rggs.check(R.id.grid_size_4);
		}
		else if(gridSize2 == 5){
			rggs.check(R.id.grid_size_5);
		}
	}

	// function to exit the game if the "exit" button is pressed
	public void exit(View view){
		this.finish();
	}

	// set the difficulty to easy
	public void difficultyEasy(View view){
		settings_difficulty = 1;
	}

	// set the difficulty to intermediate
	public void difficultyIntermediate(View view){
		settings_difficulty = 2;
	}

	// set the difficulty to advanced
	public void difficultyAdvanced(View view){
		settings_difficulty = 3;
	}

	// set the grid size to 2x2
	public void gridSize2(View view){
		settings_gridSize = 2;
	}

	// set the grid size to 3x3
	public void gridSize3(View view){
		settings_gridSize = 3;
	}

	// set the grid size to 4x4
	public void gridSize4(View view){
		settings_gridSize = 4;
	}

	// set the grid size to 5x5
	public void gridSize5(View view){
		settings_gridSize = 5;
	}

	// apply the settings (as opposed to exiting the setup screen by discarding settings changes)
	public void apply_settings(View view){
		difficulty = settings_difficulty;
		gridSize2 = settings_gridSize;
		gameInProgress = false;
		menu();
	}

	// called on load (as opposed to clicking the "new game" button)
	public void newGame_load(){

		// populates the tiles with values/characters
		generateBoard();

		// figure out which goal state is reachable based on the initially-loaded configuration
		if(mode == 2){
			getGoal();
		}
	}

	// called when user clicks "New Game" button
	public void newGame_button(View view){
		newGame_load();
	}
   
	// populates the tiles with values/characters
	public void generateBoard(){

		// equation mode
		if(mode == 1){

			// track whether or not we have set a blank tile yet
			boolean blankSet = false;

			// these are the possible tile values
			String symbol[] = {"", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "+", "=", "-", "*"};

			// for each tile, randomly pick one of the possible characters
			Random randomGenerator = new Random();
			int j = 0;
			for(int i=0; i<(gridSize*gridSize); i++){
				if(difficulty == 1){ // easy
					j = randomGenerator.nextInt(symbol.length-2);
				}
				else if(difficulty == 2){ // intermediate
					j = randomGenerator.nextInt(symbol.length-1);
				}
				else if(difficulty == 3){ // advanced
					j = randomGenerator.nextInt(symbol.length);
				}

				// set the blank
				if((blankSet == false) && (j == 0)){
					blankSet = true;
					blank = (i+1); // blank is 1 - 25
				}

				// if we pick blank, but the blank tile is already set, choose another character
				else{
					while(j == 0){
						if(difficulty == 1){ // easy
							j = randomGenerator.nextInt(symbol.length-2);
						}
						else if(difficulty == 2){ // intermediate
							j = randomGenerator.nextInt(symbol.length-1);
						}
						else if(difficulty == 3){ // advanced
							j = randomGenerator.nextInt(symbol.length);
						}
					}
				}

				// assign the character to the tile array (will be set to the tiles themselves later, only if the configuration is valid overall)
				tileText[i] = symbol[j];
				setTileDrawableId(i, symbol[j]);
			}

			// verify that we have enough valid equations
			if((blankSet == false) || (getPossibleAnswers() < minimumAnswersOnANewBoard)){

				// if there are not enough valid equations, re-generate the board
				generateBoard();
			}
			else{

				// if the configuration is valid overall, set the tile values
				// from the tileText[] array, populated above
				setTiles();
			}

			// update various text fields
			EditText lt = (EditText) findViewById(R.id.levelTitle);
			lt.setText("Level "+level+" of "+numberOfLevels);

			EditText edt = (EditText) findViewById(R.id.equationsDoneTitle);
			edt.setText("Equations Found:\r\n "+equationsFound+" of "+levelRequirements[level-1]+" ("+Integer.toString(getPossibleAnswers())+" possible)");
		}

		// number-ordering mode (mode 2)
		else{// if(gridSize != 2){

			// these are the possible tile values
			String symbol[] = {"", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"};

			// for each tile, randomly pick one of the possible characters
			Random randomGenerator = new Random();
			int j = 0;
			for(int i=0; i<(gridSize*gridSize); i++){
				j = randomGenerator.nextInt((gridSize*gridSize));
				if(symbol[j] != "#"){

					// set the blank
					if((j == 0)){
						blank = (i+1); // blank is 1 - 25
					}

					// assign the character to the tile array (will be set to the tiles themselves later, only if the configuration is valid overall)
					tileText[i] = symbol[j];
					setTileDrawableId(i, symbol[j]);

					// mark this tile's value as placed
					symbol[j] = "#";
		   	   	}

				// this tile value was already placed
				else{
					i--;
				}
			}

			// set the tile values from the tileText[] array, populated above
			setTiles();

			// do not start in the winning state
			if(winningState()){
				generateBoard();
			}
			else if(gridSize == 2){
				boolean bad = true;
				     if((tileText[0] == "") && (tileText[1] == "1") && (tileText[2] == "3") && (tileText[3] == "2")){bad = false;}
				else if((tileText[0] == "") && (tileText[1] == "3") && (tileText[2] == "2") && (tileText[3] == "1")){bad = false;}
				else if((tileText[0] == "2") && (tileText[1] == "") && (tileText[2] == "1") && (tileText[3] == "3")){bad = false;}
				else if((tileText[0] == "2") && (tileText[1] == "3") && (tileText[2] == "1") && (tileText[3] == "")){bad = false;}
				else if((tileText[0] == "3") && (tileText[1] == "") && (tileText[2] == "2") && (tileText[3] == "1")){bad = false;}
				else if((tileText[0] == "3") && (tileText[1] == "1") && (tileText[2] == "") && (tileText[3] == "2")){bad = false;}
				if(bad){
					generateBoard();
				}
			}
		}

		// mark that there is a game in progress (the "resume game" button will now be visible in the menu screen until the game is won)
		gameInProgress = true;
	}

	// array to link integer i with it's text-equivalent, and the resource ID of the associated tile
	public void setTileDrawableId(int i, String symbol){
			 if(symbol == "0"){tileDrawableId[i] = R.layout.tile0;}
		else if(symbol == "1"){tileDrawableId[i] = R.layout.tile1;}
		else if(symbol == "2"){tileDrawableId[i] = R.layout.tile2;}
		else if(symbol == "3"){tileDrawableId[i] = R.layout.tile3;}
		else if(symbol == "4"){tileDrawableId[i] = R.layout.tile4;}
		else if(symbol == "5"){tileDrawableId[i] = R.layout.tile5;}
		else if(symbol == "6"){tileDrawableId[i] = R.layout.tile6;}
		else if(symbol == "7"){tileDrawableId[i] = R.layout.tile7;}
		else if(symbol == "8"){tileDrawableId[i] = R.layout.tile8;}
		else if(symbol == "9"){tileDrawableId[i] = R.layout.tile9;}
		else if(symbol == "10"){tileDrawableId[i] = R.layout.tile10;}
		else if(symbol == "11"){tileDrawableId[i] = R.layout.tile11;}
		else if(symbol == "12"){tileDrawableId[i] = R.layout.tile12;}
		else if(symbol == "13"){tileDrawableId[i] = R.layout.tile13;}
		else if(symbol == "14"){tileDrawableId[i] = R.layout.tile14;}
		else if(symbol == "15"){tileDrawableId[i] = R.layout.tile15;}
		else if(symbol == "16"){tileDrawableId[i] = R.layout.tile16;}
		else if(symbol == "17"){tileDrawableId[i] = R.layout.tile17;}
		else if(symbol == "18"){tileDrawableId[i] = R.layout.tile18;}
		else if(symbol == "19"){tileDrawableId[i] = R.layout.tile19;}
		else if(symbol == "20"){tileDrawableId[i] = R.layout.tile20;}
		else if(symbol == "21"){tileDrawableId[i] = R.layout.tile21;}
		else if(symbol == "22"){tileDrawableId[i] = R.layout.tile22;}
		else if(symbol == "23"){tileDrawableId[i] = R.layout.tile23;}
		else if(symbol == "24"){tileDrawableId[i] = R.layout.tile24;}
		else if(symbol == "25"){tileDrawableId[i] = R.layout.tile25;}
		else if(symbol == "-"){tileDrawableId[i] = R.layout.tilem;}
		else if(symbol == "+"){tileDrawableId[i] = R.layout.tilep;}
		else if(symbol == "X"){tileDrawableId[i] = R.layout.tilex;}
		else if(symbol == "*"){tileDrawableId[i] = R.layout.tilex2;}
		else if(symbol == "="){tileDrawableId[i] = R.layout.tilee;}
		else if(symbol == ""){tileDrawableId[i] = R.layout.tileb;}
	}

	// figure out which goal state is reachable based on the initially-loaded configuration (mode 2 only)
	public void getGoal(){

		// determine if the goal is in rows, or in the alternative goal state (spiral)
		int total = 0;
		for(int i=0; i<(gridSize*gridSize); i++){
			for(int j=i; j<(gridSize*gridSize); j++){
				//if(tileText[j] == "1"){continue;}
				if(tileText[i] == ""){continue;}
				if(tileText[j] == ""){continue;}
				if(Integer.parseInt(tileText[j]) < Integer.parseInt(tileText[i])){total++;}
			}
		}
		if((total%2) == 0){
			goalTypeAlternative = false;
		}
		else{
			goalTypeAlternative = true;
		}

		// 2x2 is different
		if(gridSize == 2){
			if((tileText[0] == "") || (tileText[1] == "")){
				if(Integer.parseInt(tileText[2]) < Integer.parseInt(tileText[3])){
					goalTypeAlternative = true;
				}
				else{
					goalTypeAlternative = false;
				}
			}
			else if((tileText[2] == "") || (tileText[3] == "")){
				if(Integer.parseInt(tileText[0]) < Integer.parseInt(tileText[1])){
					goalTypeAlternative = true;
				}
				else{
					goalTypeAlternative = false;
				}
			}
		}

		// update the goal-preview
		setGoalTiles();
	}

	// update the goal-preview to reflect the goal state that it actually reachable
	public void setGoalTiles(){

		// spiral, not rows
		if(goalTypeAlternative){
			if(gridSize == 3){

				// update the goal-preview tiles
				ImageButton tileg = (ImageButton) findViewById(R.id.tile1g);
				tileg.setBackgroundResource(R.layout.tile1);
				tileg = (ImageButton) findViewById(R.id.tile2g);
				tileg.setBackgroundResource(R.layout.tile2);
				tileg = (ImageButton) findViewById(R.id.tile3g);
				tileg.setBackgroundResource(R.layout.tile3);
				tileg = (ImageButton) findViewById(R.id.tile6g);
				tileg.setBackgroundResource(R.layout.tile8);
				tileg = (ImageButton) findViewById(R.id.tile7g);
				tileg.setBackgroundResource(R.layout.tileb);
				tileg = (ImageButton) findViewById(R.id.tile8g);
				tileg.setBackgroundResource(R.layout.tile4);
				tileg = (ImageButton) findViewById(R.id.tile11g);
				tileg.setBackgroundResource(R.layout.tile7);
				tileg = (ImageButton) findViewById(R.id.tile12g);
				tileg.setBackgroundResource(R.layout.tile6);
				tileg = (ImageButton) findViewById(R.id.tile13g);
				tileg.setBackgroundResource(R.layout.tile5);

				// hide the goal-preview tiles that should not be shown, based on the grid size
				hide_goal_tiles3();
			}
			else if(gridSize == 4){

				// update the goal-preview tiles
				ImageButton tileg = (ImageButton) findViewById(R.id.tile1g);
				tileg.setBackgroundResource(R.layout.tile1);
				tileg = (ImageButton) findViewById(R.id.tile2g);
				tileg.setBackgroundResource(R.layout.tile2);
				tileg = (ImageButton) findViewById(R.id.tile3g);
				tileg.setBackgroundResource(R.layout.tile3);
				tileg = (ImageButton) findViewById(R.id.tile4g);
				tileg.setBackgroundResource(R.layout.tile4);
				tileg = (ImageButton) findViewById(R.id.tile6g);
				tileg.setBackgroundResource(R.layout.tile12);
				tileg = (ImageButton) findViewById(R.id.tile7g);
				tileg.setBackgroundResource(R.layout.tile13);
				tileg = (ImageButton) findViewById(R.id.tile8g);
				tileg.setBackgroundResource(R.layout.tile14);
				tileg = (ImageButton) findViewById(R.id.tile9g);
				tileg.setBackgroundResource(R.layout.tile5);
				tileg = (ImageButton) findViewById(R.id.tile11g);
				tileg.setBackgroundResource(R.layout.tile11);
				tileg = (ImageButton) findViewById(R.id.tile12g);
				tileg.setBackgroundResource(R.layout.tileb);
				tileg = (ImageButton) findViewById(R.id.tile13g);
				tileg.setBackgroundResource(R.layout.tile15);
				tileg = (ImageButton) findViewById(R.id.tile14g);
				tileg.setBackgroundResource(R.layout.tile6);
				tileg = (ImageButton) findViewById(R.id.tile16g);
				tileg.setBackgroundResource(R.layout.tile10);
				tileg = (ImageButton) findViewById(R.id.tile17g);
				tileg.setBackgroundResource(R.layout.tile9);
				tileg = (ImageButton) findViewById(R.id.tile18g);
				tileg.setBackgroundResource(R.layout.tile8);
				tileg = (ImageButton) findViewById(R.id.tile19g);
				tileg.setBackgroundResource(R.layout.tile7);

				// hide the goal-preview tiles that should not be shown, based on the grid size
				hide_goal_tiles4();
			}
			else if(gridSize == 5){

				// update the goal-preview tiles
				ImageButton tileg = (ImageButton) findViewById(R.id.tile1g);
				tileg.setBackgroundResource(R.layout.tile1);
				tileg = (ImageButton) findViewById(R.id.tile2g);
				tileg.setBackgroundResource(R.layout.tile2);
				tileg = (ImageButton) findViewById(R.id.tile3g);
				tileg.setBackgroundResource(R.layout.tile3);
				tileg = (ImageButton) findViewById(R.id.tile4g);
				tileg.setBackgroundResource(R.layout.tile4);
				tileg = (ImageButton) findViewById(R.id.tile5g);
				tileg.setBackgroundResource(R.layout.tile5);
				tileg = (ImageButton) findViewById(R.id.tile6g);
				tileg.setBackgroundResource(R.layout.tile16);
				tileg = (ImageButton) findViewById(R.id.tile7g);
				tileg.setBackgroundResource(R.layout.tile17);
				tileg = (ImageButton) findViewById(R.id.tile8g);
				tileg.setBackgroundResource(R.layout.tile18);
				tileg = (ImageButton) findViewById(R.id.tile9g);
				tileg.setBackgroundResource(R.layout.tile19);
				tileg = (ImageButton) findViewById(R.id.tile10g);
				tileg.setBackgroundResource(R.layout.tile6);
				tileg = (ImageButton) findViewById(R.id.tile11g);
				tileg.setBackgroundResource(R.layout.tile15);
				tileg = (ImageButton) findViewById(R.id.tile12g);
				tileg.setBackgroundResource(R.layout.tile24);
				tileg = (ImageButton) findViewById(R.id.tile13g);
				tileg.setBackgroundResource(R.layout.tileb);
				tileg = (ImageButton) findViewById(R.id.tile14g);
				tileg.setBackgroundResource(R.layout.tile20);
				tileg = (ImageButton) findViewById(R.id.tile15g);
				tileg.setBackgroundResource(R.layout.tile7);
				tileg = (ImageButton) findViewById(R.id.tile16g);
				tileg.setBackgroundResource(R.layout.tile14);
				tileg = (ImageButton) findViewById(R.id.tile17g);
				tileg.setBackgroundResource(R.layout.tile23);
				tileg = (ImageButton) findViewById(R.id.tile18g);
				tileg.setBackgroundResource(R.layout.tile22);
				tileg = (ImageButton) findViewById(R.id.tile19g);
				tileg.setBackgroundResource(R.layout.tile21);
				tileg = (ImageButton) findViewById(R.id.tile20g);
				tileg.setBackgroundResource(R.layout.tile8);
				tileg = (ImageButton) findViewById(R.id.tile21g);
				tileg.setBackgroundResource(R.layout.tile13);
				tileg = (ImageButton) findViewById(R.id.tile22g);
				tileg.setBackgroundResource(R.layout.tile12);
				tileg = (ImageButton) findViewById(R.id.tile23g);
				tileg.setBackgroundResource(R.layout.tile11);
				tileg = (ImageButton) findViewById(R.id.tile24g);
				tileg.setBackgroundResource(R.layout.tile10);
				tileg = (ImageButton) findViewById(R.id.tile25g);
				tileg.setBackgroundResource(R.layout.tile9);
			}
		}

		// rows, not spiral
		else{
			if(gridSize == 2){

				// update the goal-preview tiles
				ImageButton tileg = (ImageButton) findViewById(R.id.tile1g);
				tileg.setBackgroundResource(R.layout.tile1);
				tileg = (ImageButton) findViewById(R.id.tile2g);
				tileg.setBackgroundResource(R.layout.tile2);
				tileg = (ImageButton) findViewById(R.id.tile6g);
				tileg.setBackgroundResource(R.layout.tile3);
				tileg = (ImageButton) findViewById(R.id.tile7g);
				tileg.setBackgroundResource(R.layout.tileb);

				// hide the goal-preview tiles that should not be shown, based on the grid size
				hide_goal_tiles2();
			}
			else if(gridSize == 3){

				// update the goal-preview tiles
				ImageButton tileg = (ImageButton) findViewById(R.id.tile1g);
				tileg.setBackgroundResource(R.layout.tile1);
				tileg = (ImageButton) findViewById(R.id.tile2g);
				tileg.setBackgroundResource(R.layout.tile2);
				tileg = (ImageButton) findViewById(R.id.tile3g);
				tileg.setBackgroundResource(R.layout.tile3);
				tileg = (ImageButton) findViewById(R.id.tile6g);
				tileg.setBackgroundResource(R.layout.tile4);
				tileg = (ImageButton) findViewById(R.id.tile7g);
				tileg.setBackgroundResource(R.layout.tile5);
				tileg = (ImageButton) findViewById(R.id.tile8g);
				tileg.setBackgroundResource(R.layout.tile6);
				tileg = (ImageButton) findViewById(R.id.tile11g);
				tileg.setBackgroundResource(R.layout.tile7);
				tileg = (ImageButton) findViewById(R.id.tile12g);
				tileg.setBackgroundResource(R.layout.tile8);
				tileg = (ImageButton) findViewById(R.id.tile13g);
				tileg.setBackgroundResource(R.layout.tileb);

				// hide the goal-preview tiles that should not be shown, based on the grid size
				hide_goal_tiles3();
			}
			else if(gridSize == 4){

				// update the goal-preview tiles
				ImageButton tileg = (ImageButton) findViewById(R.id.tile1g);
				tileg.setBackgroundResource(R.layout.tile1);
				tileg = (ImageButton) findViewById(R.id.tile2g);
				tileg.setBackgroundResource(R.layout.tile2);
				tileg = (ImageButton) findViewById(R.id.tile3g);
				tileg.setBackgroundResource(R.layout.tile3);
				tileg = (ImageButton) findViewById(R.id.tile4g);
				tileg.setBackgroundResource(R.layout.tile4);
				tileg = (ImageButton) findViewById(R.id.tile6g);
				tileg.setBackgroundResource(R.layout.tile5);
				tileg = (ImageButton) findViewById(R.id.tile7g);
				tileg.setBackgroundResource(R.layout.tile6);
				tileg = (ImageButton) findViewById(R.id.tile8g);
				tileg.setBackgroundResource(R.layout.tile7);
				tileg = (ImageButton) findViewById(R.id.tile9g);
				tileg.setBackgroundResource(R.layout.tile8);
				tileg = (ImageButton) findViewById(R.id.tile11g);
				tileg.setBackgroundResource(R.layout.tile9);
				tileg = (ImageButton) findViewById(R.id.tile12g);
				tileg.setBackgroundResource(R.layout.tile10);
				tileg = (ImageButton) findViewById(R.id.tile13g);
				tileg.setBackgroundResource(R.layout.tile11);
				tileg = (ImageButton) findViewById(R.id.tile14g);
				tileg.setBackgroundResource(R.layout.tile12);
				tileg = (ImageButton) findViewById(R.id.tile16g);
				tileg.setBackgroundResource(R.layout.tile13);
				tileg = (ImageButton) findViewById(R.id.tile17g);
				tileg.setBackgroundResource(R.layout.tile14);
				tileg = (ImageButton) findViewById(R.id.tile18g);
				tileg.setBackgroundResource(R.layout.tile15);
				tileg = (ImageButton) findViewById(R.id.tile19g);
				tileg.setBackgroundResource(R.layout.tileb);

				// hide the goal-preview tiles that should not be shown, based on the grid size
				hide_goal_tiles4();
			}
			else if(gridSize == 5){

				// update the goal-preview tiles
				ImageButton tileg = (ImageButton) findViewById(R.id.tile1g);
				tileg.setBackgroundResource(R.layout.tile1);
				tileg = (ImageButton) findViewById(R.id.tile2g);
				tileg.setBackgroundResource(R.layout.tile2);
				tileg = (ImageButton) findViewById(R.id.tile3g);
				tileg.setBackgroundResource(R.layout.tile3);
				tileg = (ImageButton) findViewById(R.id.tile4g);
				tileg.setBackgroundResource(R.layout.tile4);
				tileg = (ImageButton) findViewById(R.id.tile5g);
				tileg.setBackgroundResource(R.layout.tile5);
				tileg = (ImageButton) findViewById(R.id.tile6g);
				tileg.setBackgroundResource(R.layout.tile6);
				tileg = (ImageButton) findViewById(R.id.tile7g);
				tileg.setBackgroundResource(R.layout.tile7);
				tileg = (ImageButton) findViewById(R.id.tile8g);
				tileg.setBackgroundResource(R.layout.tile8);
				tileg = (ImageButton) findViewById(R.id.tile9g);
				tileg.setBackgroundResource(R.layout.tile9);
				tileg = (ImageButton) findViewById(R.id.tile10g);
				tileg.setBackgroundResource(R.layout.tile10);
				tileg = (ImageButton) findViewById(R.id.tile11g);
				tileg.setBackgroundResource(R.layout.tile11);
				tileg = (ImageButton) findViewById(R.id.tile12g);
				tileg.setBackgroundResource(R.layout.tile12);
				tileg = (ImageButton) findViewById(R.id.tile13g);
				tileg.setBackgroundResource(R.layout.tile13);
				tileg = (ImageButton) findViewById(R.id.tile14g);
				tileg.setBackgroundResource(R.layout.tile14);
				tileg = (ImageButton) findViewById(R.id.tile15g);
				tileg.setBackgroundResource(R.layout.tile15);
				tileg = (ImageButton) findViewById(R.id.tile16g);
				tileg.setBackgroundResource(R.layout.tile16);
				tileg = (ImageButton) findViewById(R.id.tile17g);
				tileg.setBackgroundResource(R.layout.tile17);
				tileg = (ImageButton) findViewById(R.id.tile18g);
				tileg.setBackgroundResource(R.layout.tile18);
				tileg = (ImageButton) findViewById(R.id.tile19g);
				tileg.setBackgroundResource(R.layout.tile19);
				tileg = (ImageButton) findViewById(R.id.tile20g);
				tileg.setBackgroundResource(R.layout.tile20);
				tileg = (ImageButton) findViewById(R.id.tile21g);
				tileg.setBackgroundResource(R.layout.tile21);
				tileg = (ImageButton) findViewById(R.id.tile22g);
				tileg.setBackgroundResource(R.layout.tile22);
				tileg = (ImageButton) findViewById(R.id.tile23g);
				tileg.setBackgroundResource(R.layout.tile23);
				tileg = (ImageButton) findViewById(R.id.tile24g);
				tileg.setBackgroundResource(R.layout.tile24);
				tileg = (ImageButton) findViewById(R.id.tile25g);
				tileg.setBackgroundResource(R.layout.tileb);
			}
		}
	}

	// hides all tiles from the goal preview that don't matter when using a 2x2 grid
	public void hide_goal_tiles2(){
		ImageButton tileg = (ImageButton) findViewById(R.id.tile3g);
		tileg.setVisibility(4); // 0 is visible; 4 is invisible
		tileg = (ImageButton) findViewById(R.id.tile4g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile5g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile8g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile9g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile10g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile11g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile12g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile13g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile14g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile15g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile16g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile17g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile18g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile19g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile20g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile21g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile22g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile23g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile24g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile25g);
		tileg.setVisibility(4);
	}

	// hides all tiles from the goal preview that don't matter when using a 3x3 grid
	public void hide_goal_tiles3(){
		ImageButton tileg = (ImageButton) findViewById(R.id.tile4g);
		tileg.setVisibility(4); // 0 is visible; 4 is invisible
		tileg = (ImageButton) findViewById(R.id.tile5g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile9g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile10g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile14g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile15g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile16g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile17g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile18g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile19g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile20g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile21g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile22g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile23g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile24g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile25g);
		tileg.setVisibility(4);
	}

	// hides all tiles from the goal preview that don't matter when using a 4x4 grid
	public void hide_goal_tiles4(){
		ImageButton tileg = (ImageButton) findViewById(R.id.tile5g);
		tileg.setVisibility(4); // 0 is visible; 4 is invisible
		tileg = (ImageButton) findViewById(R.id.tile10g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile15g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile20g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile21g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile22g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile23g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile24g);
		tileg.setVisibility(4);
		tileg = (ImageButton) findViewById(R.id.tile25g);
		tileg.setVisibility(4);
	}

	// determine if the current state is a winning state (mode 2 only)
	public boolean winningState(){

		//initialize variables
		int correctTiles = 0;
		String[] goal = new String[(gridSize*gridSize)];

		if(goalTypeAlternative == false){
			if(gridSize == 2){
				goal[0] = "1";
				goal[1] = "2";
				goal[2] = "3";
				goal[3] = "";
			}
			else if(gridSize == 3){
				goal[0] = "1";
				goal[1] = "2";
				goal[2] = "3";
				goal[3] = "4";
				goal[4] = "5";
				goal[5] = "6";
				goal[6] = "7";
				goal[7] = "8";
				goal[8] = "";
			}
			else if(gridSize == 4){
				goal[0] = "1";
				goal[1] = "2";
				goal[2] = "3";
				goal[3] = "4";
				goal[4] = "5";
				goal[5] = "6";
				goal[6] = "7";
				goal[7] = "8";
				goal[8] = "9";
				goal[9] = "10";
				goal[10] = "11";
				goal[11] = "12";
				goal[12] = "13";
				goal[13] = "14";
				goal[14] = "15";
				goal[15] = "";
			}
			else if(gridSize == 5){
				goal[0] = "1";
				goal[1] = "2";
				goal[2] = "3";
				goal[3] = "4";
				goal[4] = "5";
				goal[5] = "6";
				goal[6] = "7";
				goal[7] = "8";
				goal[8] = "9";
				goal[9] = "10";
				goal[10] = "11";
				goal[11] = "12";
				goal[12] = "13";
				goal[13] = "14";
				goal[14] = "15";
				goal[15] = "16";
				goal[16] = "17";
				goal[17] = "18";
				goal[18] = "19";
				goal[19] = "20";
				goal[20] = "21";
				goal[21] = "22";
				goal[22] = "23";
				goal[23] = "24";
				goal[24] = "";
			}

			// if the top-left tile is the blank, assume the alternative goal
			int k = 0;
			int l = (gridSize*gridSize);
			if(tileText[0] == ""){
				k++;
				l--;
			}

			// count the number of correctly-placed tiles
			for(int i=0; i<l; i++, k++){

				// check this first, since parseInt on "" crashes
				if((tileText[k] == "") || (goal[i] == "")){
					continue;
				}
				if(Integer.parseInt(tileText[k]) == Integer.parseInt(goal[i])){
					correctTiles++;
				}
			}
		}

		// alternative goal type (spiral)
		else{
			if(gridSize == 2){
				goal[0] = "1";
				goal[1] = "2";
				goal[2] = "";
				goal[3] = "3";
			}
			if(gridSize == 3){
				goal[0] = "1";
				goal[1] = "2";
				goal[2] = "3";
				goal[3] = "8";
				goal[4] = "";
				goal[5] = "4";
				goal[6] = "7";
				goal[7] = "6";
				goal[8] = "5";
			}
			else if(gridSize == 4){
				goal[0] = "1";
				goal[1] = "2";
				goal[2] = "3";
				goal[3] = "4";
				goal[4] = "12";
				goal[5] = "13";
				goal[6] = "14";
				goal[7] = "5";
				goal[8] = "11";
				goal[9] = "";
				goal[10] = "15";
				goal[11] = "6";
				goal[12] = "10";
				goal[13] = "9";
				goal[14] = "8";
				goal[15] = "7";
			}
			else if(gridSize == 5){
				goal[0] = "1";
				goal[1] = "2";
				goal[2] = "3";
				goal[3] = "4";
				goal[4] = "5";
				goal[5] = "16";
				goal[6] = "17";
				goal[7] = "18";
				goal[8] = "19";
				goal[9] = "6";
				goal[10] = "15";
				goal[11] = "24";
				goal[12] = "";
				goal[13] = "20";
				goal[14] = "7";
				goal[15] = "14";
				goal[16] = "23";
				goal[17] = "22";
				goal[18] = "21";
				goal[19] = "8";
				goal[20] = "13";
				goal[21] = "12";
				goal[22] = "11";
				goal[23] = "10";
				goal[24] = "9";
			}

			// count the number of correctly-placed tiles
			for(int i=0; i<(gridSize*gridSize); i++){

				// check this first, since parseInt on "" crashes
				if((tileText[i] == "") || (goal[i] == "")){
					continue;
				}
				if(Integer.parseInt(tileText[i]) == Integer.parseInt(goal[i])){
					correctTiles++;
				}
			}
		}

		// if all tiles are correct, return true (this is a winning state)
		if(correctTiles == ((gridSize*gridSize)-1)){ // already know blank exists, it must be correct since the other 24 are
			return true;
		}
		return false;
	}

	// count and return the number of possible solutions (mode 1 only)
	public int getPossibleAnswers(){

		// track the current number of possible solutions
		int possibleSolutions = 0;

		// track possible operations
		boolean operation_equals = false;
		boolean operation_add = false;
		boolean operation_subtract = false;
		boolean operation_multiply = false;

		// initialize variables
		int[] digit = new int[(gridSize+gridSize)];
		for(int i=0; i<(gridSize+gridSize); i++){
			digit[i] = 0;
		}

		// get the number of digits and various operators
		for(int i=0; i<(gridSize+gridSize); i++){
			for(int j=0; j<((gridSize*gridSize)); j++){
				if((tileText[j] == "0") || (tileText[j] == "1") || (tileText[j] == "2") || (tileText[j] == "3") || (tileText[j] == "4") || (tileText[j] == "5") || (tileText[j] == "6") || (tileText[j] == "7") || (tileText[j] == "8") || (tileText[j] == "9")){
					if(Integer.parseInt(tileText[j]) == i){
						digit[i]++;
					}
				}
				else if(tileText[j] == "="){
					operation_equals = true;
				}
				else if(tileText[j] == "+"){
					operation_add = true;
				}
				else if(tileText[j] == "-"){
					operation_subtract = true;
				}
				else if((tileText[j] == "*") || (tileText[j] == "X")){
					operation_multiply = true;
				}
			}
		}

		// no equations possible if no equals sign
		if(operation_equals == false){
			return 0;
		}

		// no equations possible if no operators
		if((operation_add == false) && (operation_subtract == false) && (operation_multiply == false)){
			return 0;
		}

		// below, add the number of possible equations as appropriate
		if(digit[0] >= 3){ // (0*0=0; 0+0=0; 0-0=0)
			if(operation_add){possibleSolutions += 1;}
			if(operation_subtract){possibleSolutions += 1;}
			if(operation_multiply){possibleSolutions += 1;}
		}
		if(digit[1] >= 3){ // (1*1=1)
			if(operation_multiply){possibleSolutions += 1;}
		}
		if(digit[0] == 2){ // (0*n=0 n 1 through 9)
			if(operation_multiply){possibleSolutions += 9;}
		}
		if(digit[1] == 2){ // (0+1=1; 1-1=0; 2-1=1; 1+1=2; 1-0=1)
			if(operation_add){possibleSolutions += 2;}
			if(operation_subtract){possibleSolutions += 3;}
		}
		if(digit[2] >= 2){ // (1*2=2; 2*2=4; 2+2=4; 2-2=0; 0+2=2; 2-0=2; 4-2=2)
			if(operation_add){possibleSolutions += 2;}
			if(operation_subtract){possibleSolutions += 3;}
			if(operation_multiply){possibleSolutions += 2;}
		}
		if(digit[3] >= 2){ // (1*3=3; 3*3=9; 0+3=3; 3-0=0; 6-3=3; 3+3=6; 3-3=0)
			if(operation_add){possibleSolutions += 2;}
			if(operation_subtract){possibleSolutions += 3;}
			if(operation_multiply){possibleSolutions += 2;}
		}
		if(digit[4] >= 2){ // (1*4=4; 0+4=4; 4-0=4; 4-4=0; 4+4=8; 8-4=4)
			if(operation_add){possibleSolutions += 2;}
			if(operation_subtract){possibleSolutions += 3;}
			if(operation_multiply){possibleSolutions += 1;}
		}
		if(digit[5] >= 2){ // (1*5=5; 0+5=5; 5-0=5; 5-5=0)
			if(operation_add){possibleSolutions += 1;}
			if(operation_subtract){possibleSolutions += 2;}
			if(operation_multiply){possibleSolutions += 1;}
		}
		if(digit[6] >= 2){ // (1*6=6; 0+6=6; 6-0=6; 6-6=0)
			if(operation_add){possibleSolutions += 1;}
			if(operation_subtract){possibleSolutions += 2;}
			if(operation_multiply){possibleSolutions += 1;}
		}
		if(digit[7] >= 2){ // (1*7=7; 0+7=7; 7-0=7; 7-7=0)
			if(operation_add){possibleSolutions += 1;}
			if(operation_subtract){possibleSolutions += 2;}
			if(operation_multiply){possibleSolutions += 1;}
		}
		if(digit[8] >= 2){ // (1*8=8; 0+8=8; 8-0=8; 8-8=0)
			if(operation_add){possibleSolutions += 1;}
			if(operation_subtract){possibleSolutions += 2;}
			if(operation_multiply){possibleSolutions += 1;}
		}
		if(digit[9] >= 2){ // (1*9=9; 0+9=9; 9-0=9; 9-9=0)
			if(operation_add){possibleSolutions += 1;}
			if(operation_subtract){possibleSolutions += 2;}
			if(operation_multiply){possibleSolutions += 1;}
		}
		if(digit[1] == 1){ // (1+2 to 1+8 [7]; 3-1 to 9-1 [7] 9-8 to 3-2 [7])
			if(operation_add){possibleSolutions += 7;}
			if(operation_subtract){possibleSolutions += 14;}
		}
		if(digit[2] == 1){ // (9-2 to 5-2 [5]; 9-7 to 5-3 =2 [5]; 2*3, 2*4 [2]; 2+3 to 2+7 [5])
			if(operation_add){possibleSolutions += 5;}
			if(operation_subtract){possibleSolutions += 10;}
			if(operation_multiply){possibleSolutions += 2;}
		}
		if(digit[3] == 1){ // (3+4, 3+5, 3+6 [3]; 7-4, 8-5, 9-6 [3]; 9-3, 8-3, 7-3 [3])
			if(operation_add){possibleSolutions += 3;}
			if(operation_subtract){possibleSolutions += 6;}
		}
		if(digit[4] == 1){ // (4+5, 9-4, 9-5)
			if(operation_add){possibleSolutions += 1;}
			if(operation_subtract){possibleSolutions += 2;}
		}

		// return the number of possible solutions
		return possibleSolutions;
	}

	// called after each move; checks all 5 rows and columns (10 checks total) for a valid equation
	// yes, technically only one check is needed after each move, but this is easy and plenty fast
	public void getCurrentAnswers(){

		// 5 chars long; 10 possible rows/columns
		String[][] currentlyChecking = new String[(gridSize+gridSize)][gridSize];

		// load values into the array, to be checked
		for(int i=0, j=0; i<gridSize; i++, j+=gridSize){

			// load values by rows
			for(int k=0; k<gridSize; k++){
				currentlyChecking[k][i] = tileText[(j+k)];
			}

			// load values by columns
			for(int k=0; k<gridSize; k++){
				currentlyChecking[k+gridSize][i] = tileText[(i+(k*gridSize))];
			}
		}

		// run the checks
		for(int i=0; i<(gridSize+gridSize); i++){
			check(currentlyChecking[i]);
		}
	}

	// checks for a valid equation
	public void check(String[] equation){

		// initialize variables
		boolean valid = false;
		String A = "";
		String B = "";
		String C = "";
		String O = "";
		
		// if an equals sign and an operator are in the correct positions, mark as (potentially) valid
		if(equation[1] == "="){
			if((equation[3] == "-") || (equation[3] == "+") || (equation[3] == "*") || (equation[3] == "X")){
				valid = true;
				C = equation[0];
				B = equation[2];
				A = equation[4];
				O = equation[3];
			}
		}
		else if(equation[3] == "="){
			if((equation[1] == "-") || (equation[1] == "+") || (equation[1] == "*") || (equation[1] == "X")){
				valid = true;
				A = equation[0];
				B = equation[2];
				C = equation[4];
				O = equation[1];
			}
		}

		// if a row or column is (potentially) valid, check the digits
		// if it is truly valid, update the "equations found" field and the progress bar for the current level
		if(valid){
			if((A == "0") || (A == "1") || (A == "2") || (A == "3") || (A == "4") || (A == "5") || (A == "6") || (A == "7") || (A == "8") || (A == "9")){
				if((B == "0") || (B == "1") || (B == "2") || (B == "3") || (B == "4") || (B == "5") || (B == "6") || (B == "7") || (B == "8") || (B == "9")){
					if((C == "0") || (C == "1") || (C == "2") || (C == "3") || (C == "4") || (C == "5") || (C == "6") || (C == "7") || (C == "8") || (C == "9")){
						int a = Integer.parseInt(A);
						int b = Integer.parseInt(B);
						int c = Integer.parseInt(C);
						String candidateEquation = "";
						if(O == "-"){
							if(a<b){
								int temp = a;
								a = b;
								b = temp;
							}
							if((a-b) == c){
								candidateEquation = A+O+B;
								if(uniqueEquation(candidateEquation)){
									EditText ed = (EditText) findViewById(R.id.equationsDone);
									ed.setText(ed.getText()+"Equation Found: "+candidateEquation+"\r\n");
									ProgressBar pb = (ProgressBar) findViewById(R.id.progressBar);
									pb.setProgress((equationsFound*100)/levelRequirements[level-1]);
								}
							}
						}
						else if(O == "+"){
							if((a+b) == c){
								if(a < b){candidateEquation = A+O+B;}
								else{candidateEquation = B+O+A;}
								if(uniqueEquation(candidateEquation)){
									EditText ed = (EditText) findViewById(R.id.equationsDone);
									ed.setText(ed.getText()+"Equation Found: "+candidateEquation+"\r\n");
									ProgressBar pb = (ProgressBar) findViewById(R.id.progressBar);
									pb.setProgress((equationsFound*100)/levelRequirements[level-1]);
								}
							}
						}
						else if((O == "*") || (O == "X")){
							if((a*b) == c){
								if(a < b){candidateEquation = A+O+B;}
								else{candidateEquation = B+O+A;}
								if(uniqueEquation(candidateEquation)){
									EditText ed = (EditText) findViewById(R.id.equationsDone);
									ed.setText(ed.getText()+"Equation Found: "+candidateEquation+"\r\n");
									ProgressBar pb = (ProgressBar) findViewById(R.id.progressBar);
									pb.setProgress((equationsFound*100)/levelRequirements[level-1]);
								}
							}
						}
					}
				}
			}
		}
	}

	// check if an equation is unique (we don't want to keep counting the same equation by toggling a single tile back and forth)
	public boolean uniqueEquation(String candidateEquation){

		// compare the candidate equation to each equation the player has already found
		for(int i=0; i<equationsFound; i++){
			if(completedEquations[i].compareTo(candidateEquation) == 0){ // same
				return false;
			}
		}

		// if it is unique, add it to the list, play the sound for finding a new equation, and return true
		completedEquations[equationsFound] = candidateEquation;
		equationsFound++;
		mSoundManager.playSound(sound_equation_found);
		return true;
	}

	// this is where the background image is assigned to each tile
	public void setTiles(){

		// start with the first tile...
		ImageButton this_button = (ImageButton) findViewById(R.id.tile1);
		Resources res = getResources();

		// ...and handle the rest
		for(int i=0, expectedColumnOfNextTile=2; i<(gridSize*gridSize); i++, expectedColumnOfNextTile++){

			// set the tile's background image
			this_button.setBackgroundDrawable(res.getDrawable(tileDrawableId[i]));

			// get the next applicable tile
			if(i != ((gridSize*gridSize)-1)){
				if(((expectedColumnOfNextTile%5) > gridSize) || (((expectedColumnOfNextTile%5) == 0) && (gridSize == 4))){
					while((expectedColumnOfNextTile%5) != 1){ // get the next tile in column 1
						this_button = (ImageButton) findViewById(this_button.getNextFocusForwardId());
						expectedColumnOfNextTile++;
					}
				}
				this_button = (ImageButton) findViewById(this_button.getNextFocusForwardId());
			}
		}
	}

	// figure out which direction to swap tiles
	public void moveTile(View view){

		// this is used to track a bad tile selection
		boolean moved = false;

		// get the current tile
		ImageButton this_button = (ImageButton) findViewById(view.getId());
		int tileNumber = Integer.parseInt((String) this_button.getContentDescription());

		// ensure everything is in-bounds
		if(((blank > 0) && (blank <= (gridSize*gridSize))) && ((tileNumber > 0) && (tileNumber <= (gridSize*gridSize)))){

			// moving down (same column) or moving right (same row)
			if(tileNumber < blank){

				// same column; moving down
				if((tileNumber%gridSize) == (blank%gridSize)){ 
					moveTileSound();
					moved = true;
					while(tileNumber < blank){
						swapTiles(view, tileNumber, "down");
					}
				}

				// same row; moving right
				else if(((tileNumber-1)/gridSize) == ((blank-1)/gridSize)){
					moveTileSound();
					moved = true;
					while(tileNumber < blank){
						swapTiles(view, tileNumber, "right");
					}
				}
			}

			// moving up (same column) or moving left (same row)
			else if(tileNumber > blank){

				// same column; moving up
				if((tileNumber%gridSize) == (blank%gridSize)){
					moveTileSound();
					moved = true;
					while(tileNumber > blank){
						swapTiles(view, tileNumber, "up");
					}
				}

				// same row; moving left
				else if(((tileNumber-1)/gridSize) == ((blank-1)/gridSize)){
					moveTileSound();
					moved = true;
					while(tileNumber > blank){
						swapTiles(view, tileNumber, "left");
					}
				}
			}

			// if we have not made a move by now, the tile selection was not allowed, play a sound to give feedback to the user
			if(moved == false){
				mSoundManager.playSound(sound_bad_selection);
			}
		}

		// after moving, check for a win
		if(mode == 1){

			// check the rows and columns for a valid equation
			getCurrentAnswers();

			// update the statistics (won't change if no valid equation was formed by the move)
			EditText edt = (EditText) findViewById(R.id.equationsDoneTitle);
			edt.setText("Equations Found:\r\n "+equationsFound+" of "+levelRequirements[level-1]+" ("+Integer.toString(getPossibleAnswers())+" possible)");

			// the user won this game
			if(equationsFound >= levelRequirements[level-1]){

				// show the "level up" graphic, briefly
				ImageView levelUp = (ImageView) findViewById(R.id.levelUp);
				levelUp.setVisibility(0); // 0 is visible; 4 is invisible

				// increase the level, reset the game statistics
				level++;
				equationsFound = 0;
				EditText ed = (EditText) findViewById(R.id.equationsDone);
				ed.setText("");
				ProgressBar pb = (ProgressBar) findViewById(R.id.progressBar);
				pb.setProgress(0);

				// if the user jut beat the last level, they won the not just the level, but the whole game
				if(level > numberOfLevels){

					// move to the "you won" view
					setContentView(R.layout.game_won);

					// delay 2.5 seconds (showing "you won"), before returning to the game menu screen
					Handler handler = new Handler(); 
					handler.postDelayed(new Runnable(){public void run(){ menu(); }}, 2500);
				}
				else{

					// delay 2.5 seconds (showing "level up") before hiding the "level up" graphic and loading the next level
					Handler handler = new Handler(); 
					handler.postDelayed(new Runnable(){public void run(){ ImageView levelUp = (ImageView) findViewById(R.id.levelUp); levelUp.setVisibility(4); newGame_load(); }}, 2500);
				}
			}
		}

		// after moving, check for a win
		else if(mode == 2){
			if(winningState()){

				// move to the "you won" view
				setContentView(R.layout.game_won);

				// delay 2.5 seconds (showing "you won"), before returning to the game menu screen
				Handler handler = new Handler(); 
				handler.postDelayed(new Runnable(){public void run(){ menu(); }}, 2500);
			}
		}
	}

	// swap tiles (1 or more at once)
	public void swapTiles(View view, int other_tile, String direction){

		// this is the tile we clicked on
		ImageButton other_tile_button = (ImageButton) findViewById(view.getId());

		// get the blank tile
		ImageButton blank_tile_button = null;
		if(direction == "up"){blank_tile_button = (ImageButton) findViewById(other_tile_button.getNextFocusUpId());}
		else if(direction == "down"){blank_tile_button = (ImageButton) findViewById(other_tile_button.getNextFocusDownId());}
		else if(direction == "left"){blank_tile_button = (ImageButton) findViewById(other_tile_button.getNextFocusLeftId());}
		else if(direction == "right"){blank_tile_button = (ImageButton) findViewById(other_tile_button.getNextFocusRightId());}

		// while getting the blank tile, it may be necessary to search further, if moving 2+ tiles at once
		while(Integer.parseInt((String) blank_tile_button.getContentDescription()) != blank){
			other_tile_button = blank_tile_button;
			if(direction == "up"){blank_tile_button = (ImageButton) findViewById(blank_tile_button.getNextFocusUpId());}
			else if(direction == "down"){blank_tile_button = (ImageButton) findViewById(blank_tile_button.getNextFocusDownId());}
			else if(direction == "left"){blank_tile_button = (ImageButton) findViewById(blank_tile_button.getNextFocusLeftId());}
			else if(direction == "right"){blank_tile_button = (ImageButton) findViewById(blank_tile_button.getNextFocusRightId());}
		}

		// for updating the tileText[] array that stores tile values
		int oldBlankPosition = blank-1;
		String temp = tileText[oldBlankPosition];

		// update the blank tile's position
		blank = Integer.parseInt((String) other_tile_button.getContentDescription()); // 1 to 25

		// update the tileText[] array that stores tile values
		tileText[oldBlankPosition] = tileText[blank-1];
		tileText[blank-1] = temp;

		// swap the tile background images
		Drawable bd = other_tile_button.getBackground();
		other_tile_button.setBackgroundDrawable(blank_tile_button.getBackground());
		blank_tile_button.setBackgroundDrawable(bd);
	}

	// plays the "tile moved" sound
	public void moveTileSound(){
		mSoundManager.playSound(sound_move_tile);
	}
}